local skynet = require "skynet"

local TableLogic = {}
local  maxPlayer = 4
local  maxCardCount = 13

--全部扑克数据
TableLogic.allCards =
{
	0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,       --方			2-A
	0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,		--梅				
	0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,		--红			
	0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,       --黑				
}
--去2~7
TableLogic.rmNumerCards =
{
	0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,     --方			7-A
	0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,		--梅				
	0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,		--红			
	0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,     --黑				
}
--去方块
TableLogic.rmColorCards =
{
	0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,		--梅				
	0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,		--红			
	0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,       --黑				
}

local EGameType = 
{
    CT_INVALID =                      0,         --错误类型
    CT_SINGLE =                       1,         --乌龙:单牌类型
    CT_ONE_DOUBLE =                   2,         --对子:只有一对
    CT_FIVE_TWO_DOUBLE =              3,         --二对:两对牌型
    CT_THREE =                        4,         --三条:三张牌型
    CT_FIVE_MIXED_FLUSH_NO_A =        5,         --顺子:没A杂顺
    CT_FIVE_MIXED_FLUSH_FIRST_A =     6,         --顺子:A在前顺子
    CT_FIVE_MIXED_FLUSH_BACK_A =      7,         --顺子:A在后顺子
    CT_FIVE_FLUSH =                   8,         --同花:同花
    CT_FIVE_THREE_DEOUBLE =           9,         --葫芦:三条一对
    CT_FIVE_FOUR_ONE =                10,        --铁支:四带一张
    CT_FIVE_STRAIGHT_FLUSH =          11,        --同花顺:没A同花顺
    CT_FIVE_STRAIGHT_FLUSH_FIRST_A =  12,        --同花顺:A在前同花顺
    CT_FIVE_STRAIGHT_FLUSH_BACK_A =   13,        --同花顺:A在后同花顺

    ST_SANSHUNZI =                    14,        --三顺子
    ST_SANTONGHUA =                   15,        --三同花
    ST_LIUDUIBAN =                    16,        --六对半
    ST_WUDUICHONGSAN =                17,        --五对冲三
    ST_SITAOCHONGSAN =                18,        --四套冲三
    ST_QUANHEI =                      20,        --全黑
    ST_QUANHONG =                     21,        --全红
    ST_QUANXIAO =                     22,        --全小
    ST_QUANDA =                       23,        --全大
    ST_YITIAOLONG =                   24,        --一条龙
    ST_SANTAOZHADAN =                 25,        --三炸弹
    ST_SHIERHUANGZU =                 26,        --十二皇族
    ST_SANTONGHUASHUN =               27,        --三同花顺
    ST_LITIAOHUALONG =                28,        --一条花龙
    ST_QINGLONG =                     29,        --一条青龙
}
local EGameSelectStatus = 
{
    --挑选还未完成
    UNCOMPELETE = 40,
    --挑选完成
    COMPELETE = 41,
}
local EGameChannel = 
{
    HEAD = 30,
    MIDDLE = 31, 
    TAIL = 32,
}

----------------------------------------------------
function TableLogic:RandCards(type)
	local cards = {}
	if type==0 then 
		cards = TableLogic.rmColorCards
	elseif type==1 then 
		cards = TableLogic.rmNumerCards
	elseif type==2 then 
		cards = TableLogic.allCards
	end

    local index = 0
    local temp = 0
    for i=1, #cards do
        index = math.random(1, #cards)
        temp = cards[i]
        cards[i] = cards[index]
        cards[index] = temp
    end

    return cards
end

function TableLogic:StartGameTestFaPai(allCards, chairObj)
	skynet.error("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
	local fapai_server = skynet.getenv('N_fapai_server')
    local fapai_file = skynet.getenv('fapai_file')
    local Tables 
    if fapai_server and fapai_file then 
        local httpc = require "http.httpc"
        local status, body =  httpc.get(fapai_server, fapai_file, {})
        skynet.error('get fapai from ', (fapai_server or ''), (fapai_file or ''), 'status is', status)
        local TablesFun = load(body)
        if TablesFun then 
        	Tables = TablesFun() 
        end
        if not Tables then 	
        	skynet.error('parse FaPai.lua error') 
        	return 
        end 
    else
    	local logicPath = skynet.getenv('fapai_path')
    	--local logicPath = skynet.getenv('gamelogic_path')
    	if not logicPath then 
        	return 
    	end
    	skynet.error('logicPath is'..logicPath)
    	local fileFaPai = io.open(logicPath..'ssz_fapai.lua',rb)
    	local value = nil
    	if fileFaPai then 
        	value = fileFaPai:read("*a")
        	fileFaPai:close() 
        	if value==nil then 
        		return
        	end
        	Tables = load(value)()
    	else 
        	skynet.error('no fapai file!!!') 
        	return 
    	end
   	end

    --根据playerID找发牌Table
    local Table
    for i=0, maxPlayer-1 do
    	if chairObj[i] == nil then 
    		break
    	end
    	skynet.error("chairObj[i].player.nPlayerId= ", math.modf(chairObj[i].player.nPlayerId))
    	if Tables[math.modf(chairObj[i].player.nPlayerId)] ~= nil then 
    		Table = Tables[math.modf(chairObj[i].player.nPlayerId)] 
    		break
    	end
    end
    
    if not Table then skynet.error('no Id of the plays!!!') return end     --没有该玩家的脚本


    skynet.error("Table.Enable=", Table.Enable)
    if Table.Enable==0 then 
        return 
    end  
    local pai = {Table.pai_1, Table.pai_2, Table.pai_3, Table.pai_4}
    --手牌
    for i=1, #pai do
        for j=1, maxCardCount do
            for key, value in pairs(allCards) do
                if pai[i][j] == value then 
                    temp = allCards[13*(i-1)+j]
                    allCards[13*(i-1)+j] = allCards[key]
                    allCards[key] = temp
                end
            end
        end
    end

    return allCards
end

-------------------------------------------------------
function TableLogic:CalculateCard(chair, gameType)

    local iRet = self:CalculateSTCard(chair, gameType)
    if iRet~=0 and iRet~=nil then 
        chair.chAdViseData.cardgroup = iRet
    end

    self:CalculateCTCard(chair)
end

function TableLogic:CalculateSTCard(chair, gameType)
    --排序
    self:SortPuke(chair.chCardData)

    --先计算特殊牌型
    local iRet = false

    --一条清龙
    iRet = self:IsYiTiaoQingLong(chair.chCardData)
    if iRet then
        return EGameType.ST_QINGLONG
    end
    --一条花龙
    iRet = self:IsYiTiaoLong(chair.chCardData)
    if iRet then
        return EGameType.ST_YITIAOLONG
    end
    --十二皇族
    iRet = self:IsShiErHuangZu(chair.chCardData)
    if iRet then
        return EGameType.ST_SHIERHUANGZU
    end
    --三同花顺
    iRet = self:IsSanTongHuaShun(chair.chCardData)
    if iRet then
        return EGameType.ST_SANTONGHUASHUN
    end
    --三套炸弹
    iRet = self:IsSanTaoZhaDan(chair.chCardData)
    if iRet then
        return EGameType.ST_SANTAOZHADAN
    end
    --全大
    iRet = self:IsQuanDa(chair.chCardData, gameType)
    if iRet then
        return EGameType.ST_QUANDA
    end
     --全小
    iRet = self:IsQuanXiao(chair.chCardData)
    if iRet then
        return EGameType.ST_QUANXIAO
    end
    --全黑
    iRet = self:IsQuanHei(chair.chCardData)
    if iRet then
        return EGameType.ST_QUANHEI
    end
    --全红
    iRet = self:IsQuanHong(chair.chCardData)
    if iRet then
        return EGameType.ST_QUANHONG
    end
    ---四套冲三
    iRet = self:IsSiTaoCHSan(chair.chCardData)
    if iRet then
        return EGameType.ST_SITAOCHONGSAN
    end
     --五对冲三
    iRet = self:IsWuDuiChSan(chair.chCardData)
    if iRet then
        return EGameType.ST_WUDUICHONGSAN
    end
    --六对半
    iRet = self:IsLiuDuiBan(chair.chCardData)
    if iRet then
        return EGameType.ST_LIUDUIBAN
    end
    --三同花
    iRet = self:IsSanTongHua(chair.chCardData)
    if iRet then
        return EGameType.ST_SANTONGHUA
    end
    --三顺子
    iRet = self:IsSanShunZi(chair.chCardData)
    if iRet then
        return EGameType.ST_SANSHUNZI
    end
end

--三同花顺
function TableLogic:IsSanTongHuaShun(chCardData, bSelectTable)
	local valueTable = {}
	local colorTable = {}

	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			valueTable[i] = chCardData[i]%16
			colorTable[i] = math.modf(chCardData[i]/16)
			bSelectTable[i] = false
		end
	end

	--拿一次同花顺
	if self:CheckHasTongHuaShun(valueTable, colorTable, bSelectTable)==true then 
		if self:CheckHasTongHuaShun(valueTable, colorTable, bSelectTable)==true then 
			skynet.error("取到两个同花顺了！")
			--拿到了两次的5张同花顺，那此时余下的3张看看是不是
			local leftTable = {}
			local pos = 0
			for i=1, 3 do
				pos = self:GetUnSelectPos(bSelectTable)
				table.insert(leftTable, chCardData[pos])
				bSelectTable[pos] = true
			end
			self:SortPuke(leftTable)

			skynet.error("leftTable[1]%16=", leftTable[1]%16)
			skynet.error("leftTable[2]%16=", leftTable[2]%16)
			skynet.error("leftTable[3]%16=", leftTable[3]%16)
			if (leftTable[1]%16)+1==leftTable[2]%16 and (leftTable[2]%16)+1==leftTable[3]%16 then 
				--是顺子再检测是否同花
				if math.modf(leftTable[1]/16)==math.modf(leftTable[2]/16) and math.modf(leftTable[2]/16)==math.modf(leftTable[3]/16) then 
					return true
				end
			end
		end
	end

	return false
end

--三顺子
function TableLogic:IsSanShunZi(chCardData, bSelectTable)
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			bSelectTable[i] = false
		end
	end
	local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end

	if self:CheckHasShunZi(5, valueTable, bSelectTable)==true then 
		if self:CheckHasShunZi(5, valueTable, bSelectTable)==true then 
			local leftTable = {}
			for i=1, maxCardCount do
				if bSelectTable[i] == false then 
					table.insert(leftTable, chCardData[i])
				end
			end
				
			if #leftTable < 3 then 
				return false
			end
			self:SortPuke(leftTable)
			local v1 = leftTable[1]%16
			local v2 = leftTable[2]%16
			local v3 = leftTable[3]%16
			if v1+1==v2 and v2+1==v3 then 
				return true
			end
			
		end
	end
	return false
end

--三同花
function TableLogic:IsSanTongHua(chCardData, bSelectTable)
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			bSelectTable[i] = false
		end
	end
	local colorTable = {}
	for i=1, maxCardCount do 
        colorTable[i] = math.modf(chCardData[i]/16)
    end

	if self:CheckHasTongHua(colorTable, bSelectTable) then 
		if self:CheckHasTongHua(colorTable, bSelectTable) then 
			local leftTable = {}
			for i=1, maxCardCount do
				if bSelectTable[i] == false then 
					table.insert(leftTable, chCardData[i])
				end
			end
			local c1 = math.modf(leftTable[1]/16)
			local c2 = math.modf(leftTable[2]/16)
			local c3 = math.modf(leftTable[3]/16)
			if c1==c2 and c2==c3 then 
				return true
			end
			
		end
	end

	return false
end

--六对半
function TableLogic:IsLiuDuiBan(chCardData, bSelectTable)
	local valueTable = {}
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			bSelectTable[i] = false
			valueTable[i] = chCardData[i]%16
		end
	end

    for i=1, 6 do
    	if self:CheckHasSameCards(2, valueTable, bSelectTable)==false then 
    		return false
    	end 
    end

    return true
end

--五对冲三
function TableLogic:IsWuDuiChSan(chCardData, bSelectTable)
	local valueTable = {}
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			bSelectTable[i] = false
			valueTable[i] = chCardData[i]%16
		end
	end
    for i=1, 5 do
    	--[[
    	skynet.error("###############IsWuDuiChSan###############")
    	for i=1, #bSelectTable do
       	 	skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    	end
    	for i=1, #bSelectTable do
       	 	skynet.error("valueTable["..i.."]= ",valueTable[i])
    	end
    	--]]
    	if self:CheckHasSameCards(2, valueTable, bSelectTable)==false then 
    		return false
    	end 
    end
    if self:CheckHasSameCards(3, valueTable, bSelectTable)==true then 
    	return true
    end

    return false
end

--四套冲三
function TableLogic:IsSiTaoCHSan(chCardData, bSelectTable)
	local valueTable = {}
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #chCardData do
			bSelectTable[i] = false
			valueTable[i] = chCardData[i]%16
		end
	end

    for i=1, 4 do
    	--[[
    	skynet.error("###############IsSiTaoCHSan###############")
    	for i=1, #bSelectTable do
       	 	skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    	end
    	for i=1, #bSelectTable do
       	 	skynet.error("valueTable["..i.."]= ",valueTable[i])
    	end
    	--]]
    	if self:CheckHasSameCards(3, valueTable, bSelectTable)==false then 
    		skynet.error("IsSiTaoCHSan!")
    		return false
    	end 
    	--[[
    	skynet.error("###############After IsSiTaoCHSan###############")
    	for i=1, #bSelectTable do
       	 	skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    	end
    	--]]
    end

    return true
end

--全黑
function TableLogic:IsQuanHei(chCardData)
    local colorTable = {}
    for i=1, maxCardCount do 
        colorTable[i] = math.modf(chCardData[i]/16)
    end

    for i=1, maxCardCount do
        if colorTable[i]==1 or colorTable[i]==3 then
            return false
        end
    end

    return true
end

--全红
function TableLogic:IsQuanHong(chCardData)
    local colorTable = {}
    for i=1, maxCardCount do 
        colorTable[i] = math.modf(chCardData[i]/16)
    end

    for i=1, maxCardCount do
        if colorTable[i]==2 or colorTable[i]==4 then
            return false
        end
    end

    return true 
end

--全大
function TableLogic:IsQuanDa(chCardData, gameType)
	skynet.error("gameType=", gameType)
	--去掉2~7时没有全大
	if gameType==1 then 
		return false
	end

    local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end

    for i=1, maxCardCount do
        if valueTable[i] < 8 then
            return false
        end
    end

    return true 
end

--全小
function TableLogic:IsQuanXiao(chCardData)
    local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end

    for i=1, maxCardCount do
        if valueTable[i] > 8 then
            return false
        end
    end

    return true 
end

--三套炸弹
function TableLogic:IsSanTaoZhaDan(chCardData, bSelectTable)
	local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end

    for i=1, 3 do
    	if self:CheckHasSameCards(4, valueTable, bSelectTable)==false then 
    		return false
    	end
    end

    return true
end

--十二皇族
function TableLogic:IsShiErHuangZu(chCardData)
    local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end

    for i=1, maxCardCount do
        if valueTable[i] < 10 then
            return false
        end
    end

    return true
end

--一条龙
function TableLogic:IsYiTiaoLong(chCardData)
	local valueTable = {}
    for i=1, maxCardCount do 
        valueTable[i] = chCardData[i]%16
    end

    self:SortValue(valueTable)
    
    for i=1, maxCardCount-1 do
        if valueTable[i+1] ~= valueTable[i] + 1 then
            return false
        end
    end

    return true
end

--一条清龙
function TableLogic:IsYiTiaoQingLong(chCardData)
    if self:IsYiTiaoLong(chCardData)==false then 
    	return false
    end

    local colorTable = {}
    for i=1, maxCardCount do 
        colorTable[i] = math.modf(chCardData[i]/16)
    end
    for i=1, maxCardCount-1 do
        if colorTable[i+1] ~= colorTable[i] then
            return false
        end
    end

  	return true
end

--检测普通牌型
function TableLogic:CalculateCTCard(chair)
    local valueTable = {}
    local colorTable = {}
    local bSelectTable = {}
    for i=1, maxCardCount do 
        colorTable[i] = math.modf(chair.chCardData[i]/16)
        valueTable[i] = chair.chCardData[i]%16
        bSelectTable[i] = false
    end

    --[[
    skynet.error("---------------MiddleFirst---------------")
    for i=1, #valueTable do
        skynet.error("valueTable["..i.."]= ",valueTable[i])
    end
    for i=1, #colorTable do
        --skynet.error("colorTable["..i.."]= ",colorTable[i])
    end
    for i=1, #bSelectTable do
        skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    end
	--]]

    --依策划所说，必须尾道>中道>头道  所以，从大到小依次找尾道中头
    self:FindTypeCards(chair, valueTable, colorTable, bSelectTable, EGameChannel.TAIL)
    --
    self:FindTypeCards(chair, valueTable, colorTable, bSelectTable, EGameChannel.MIDDLE)
    --
    self:FindTypeCards(chair, valueTable, colorTable, bSelectTable, EGameChannel.HEAD)
    
    --[[
    skynet.error("###############Before###############")
    for i=1, #bSelectTable do
        skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.head[i]~=nil then 
            --chair.chAdViseData.head[i] = chair.chAdViseData.head[i]%16
            skynet.error("chair.chAdViseData.head["..i.."]= ",  chair.chAdViseData.head[i]%16)
        end
        
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.middle[i]~=nil then 
            --chair.chAdViseData.middle[i] = chair.chAdViseData.middle[i]%16
            skynet.error("chair.chAdViseData.middle["..i.."]= ",  chair.chAdViseData.middle[i]%16)
        end
       
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.tail[i]~=nil then 
            --chair.chAdViseData.tail[i] = chair.chAdViseData.tail[i]%16
            skynet.error("chair.chAdViseData.tail["..i.."]= ",  chair.chAdViseData.tail[i]%16)
        end
       
    end
    --]]

    --将没有拿到牌的位置补充完整
    self:GiveAllCards(chair, bSelectTable)

    --再判断下推荐的牌型，3道有没有大小错误
    self:CheckHasErrorType(chair)

    --再给三道牌排序，按照从大到小排
    self:SortThreePuke(chair.chAdViseData)

    --[[
    skynet.error("###############After###############")
     for i=1, #bSelectTable do
        skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.head[i]~=nil then 
            --chair.chAdViseData.head[i] = chair.chAdViseData.head[i]%16
            skynet.error("chair.chAdViseData.head["..i.."]= ",  chair.chAdViseData.head[i]%16)
        end
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.middle[i]~=nil then 
            --chair.chAdViseData.middle[i] = chair.chAdViseData.middle[i]%16
            skynet.error("chair.chAdViseData.middle["..i.."]= ",  chair.chAdViseData.middle[i]%16)
        end    
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chair.chAdViseData.tail[i]~=nil then 
            --chair.chAdViseData.tail[i] = chair.chAdViseData.tail[i]%16
            skynet.error("chair.chAdViseData.tail["..i.."]= ",  chair.chAdViseData.tail[i]%16)
        end
    end
    --]]
end

function TableLogic:GetUnSelectPos(bSelectTable)
    for i=1, #bSelectTable do
        if bSelectTable[i]==false then 
            return i
        end
    end

    return 0
end

function TableLogic:SortThreePuke(chAdViseData)

	--[[
    skynet.error("###############Before SortThreePuke###############")
    for i=0, 7 do
        if chAdViseData.head[i]~=nil then 
            --chair.chAdViseData.head[i] = chair.chAdViseData.head[i]%16
            skynet.error("chair.chAdViseData.head["..i.."]= ",  chAdViseData.head[i])
        end
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chAdViseData.middle[i]~=nil then 
            --chair.chAdViseData.middle[i] = chair.chAdViseData.middle[i]%16
            skynet.error("chair.chAdViseData.middle["..i.."]= ",  chAdViseData.middle[i])
        end    
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chAdViseData.tail[i]~=nil then 
            --chair.chAdViseData.tail[i] = chair.chAdViseData.tail[i]%16
            skynet.error("chair.chAdViseData.tail["..i.."]= ",  chAdViseData.tail[i])
        end
    end
    --]]

	--头道
	local valueTable = {}
	for i=2, 4 do
		valueTable[i-1] = chAdViseData.head[i]
	end
	self:SortPukeBigToSmall(valueTable)
	self:SortSameValueColor(valueTable)
	for i=2, 4 do
		chAdViseData.head[i] = valueTable[i-1]
	end
	--中道
	valueTable = {}
	for i=2, 6 do
		valueTable[i-1] = chAdViseData.middle[i]
	end
	self:SortPukeBigToSmall(valueTable)
	self:SortSameValueColor(valueTable)
	for i=2, 6 do
		chAdViseData.middle[i] = valueTable[i-1]
	end
	--尾道
	valueTable = {}
	for i=2, 6 do
		valueTable[i-1] = chAdViseData.tail[i]
	end
	self:SortPukeBigToSmall(valueTable)
	self:SortSameValueColor(valueTable)
	for i=2, 6 do
		chAdViseData.tail[i] = valueTable[i-1]
	end

	--[[
    skynet.error("###############After SortThreePuke###############")
    for i=0, 7 do
        if chAdViseData.head[i]~=nil then 
            --chair.chAdViseData.head[i] = chair.chAdViseData.head[i]%16
            skynet.error("chair.chAdViseData.head["..i.."]= ",  chAdViseData.head[i])
        end
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chAdViseData.middle[i]~=nil then 
            --chair.chAdViseData.middle[i] = chair.chAdViseData.middle[i]%16
            skynet.error("chair.chAdViseData.middle["..i.."]= ",  chAdViseData.middle[i])
        end    
    end
    skynet.error("---------------------------")
    for i=0, 7 do
        if chAdViseData.tail[i]~=nil then 
            --chair.chAdViseData.tail[i] = chair.chAdViseData.tail[i]%16
            skynet.error("chair.chAdViseData.tail["..i.."]= ",  chAdViseData.tail[i])
        end
    end
    --]]
end
------------------------------------------------------------------------
function TableLogic:CompareTwoCards(card1, card2)
	--skynet.error("card1=", card1)
	--skynet.error("card2=", card2)
	if card1[1] > card2[1] then 
		return 1
	elseif card1[1] < card2[1] then 
		return 2
	else 
		return self:CompareSameTypeCards(card1, card2)
	end
end

function TableLogic:CompareSameTypeCards(card1, card2)
	local iRet = 0

	repeat
		--都是同花顺
		if card1[1]==EGameType.CT_FIVE_STRAIGHT_FLUSH then
			iRet = self:CompareTongHuaShun(card1, card2)
			break
		--都是铁支 	
		elseif card1[1]==EGameType.CT_FIVE_FOUR_ONE then 
			iRet = self:CompareTieZhi(card1, card2)
			break
		--都是葫芦 
		elseif card1[1]==EGameType.CT_FIVE_THREE_DEOUBLE then 
			iRet = self:CompareHuLu(card1, card2)
			break
		--都是同花
		elseif card1[1]==EGameType.CT_FIVE_FLUSH then 
			iRet = self:CompareTongHua(card1, card2)
			break
		--都是顺子
		elseif card1[1]==EGameType.CT_FIVE_MIXED_FLUSH_NO_A then 
			iRet = self:CompareShunZi(card1, card2)
			break
		--都是三条
		elseif card1[1]==EGameType.CT_THREE then 
			iRet = self:CompareSanTiao(card1, card2)
			break
		--都是两对
		elseif card1[1]==EGameType.CT_FIVE_TWO_DOUBLE then 
			iRet = self:CompareLiangDui(card1, card2)
			break
		--都是对子
		elseif card1[1]==EGameType.CT_ONE_DOUBLE then 
			iRet = self:CompareDuiZi(card1, card2)
			break
		--都是杂牌
		elseif card1[1]==EGameType.CT_SINGLE then 
			iRet = self:CompareZaPai(card1, card2)
			break
		end
	until true

	return iRet
end

function TableLogic:CheckHasErrorType(chair)
	local iRet = 0

	if chair.chAdViseData.tail[1]==chair.chAdViseData.middle[1] then 
		iRet = self:CompareSameTypeCards(chair.chAdViseData.middle, chair.chAdViseData.tail)
	end

	if iRet==1 then 
		local tempValue = {}
		tempValue.middle = {}
		for i=2, 6 do
			tempValue.middle[i] = chair.chAdViseData.middle[i]
		end
		for i=2, 6 do
			chair.chAdViseData.middle[i] = chair.chAdViseData.tail[i]
		end
		for i=2, 6 do
			chair.chAdViseData.tail[i] = tempValue.middle[i]
		end
	end
end

--同花顺比较
function TableLogic:CompareTongHuaShun(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end
	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	for i=1, #valueTable1 do
		for j=i, #valueTable2 do
			if valueTable1[i]==valueTable2[j] then 
				break
			elseif valueTable1[i]>valueTable2[j] then 
				return 1
			elseif valueTable1[i]<valueTable2[j] then 
				return 2
			end
		end
	end

	--能到这里说明两个同花顺点数相同，则比花色
	local color1 = math.modf(card1[2]/16)
	local color2 = math.modf(card2[2]/16)
	if color1 > color2 then 
		return 1
	else
		return 2
	end
end

--铁支比较
function TableLogic:CompareTieZhi(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end

	local iRet1,bFindTable1 = self:CheckHasSameCards(4, valueTable1)
	local iRet2,bFindTable2 = self:CheckHasSameCards(4, valueTable2)

	if valueTable1[bFindTable1[1]]>valueTable2[bFindTable2[1]] then 
		return 1
	else
		return 2
	end

	return 
end

--葫芦比较
function TableLogic:CompareHuLu(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end

	local iRet1,bFindTable1 = self:CheckHasSameCards(3, valueTable1)
	local iRet2,bFindTable2 = self:CheckHasSameCards(3, valueTable2)

	if valueTable1[bFindTable1[1]]>valueTable2[bFindTable2[1]] then 
		return 1
	else
		return 2
	end
end

--同花比较
function TableLogic:CompareTongHua(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end
	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	for i=1, #valueTable1 do
		for j=i, #valueTable2 do
			if valueTable1[i]==valueTable2[j] then 
				break
			elseif valueTable1[i]>valueTable2[j] then 
				return 1
			elseif valueTable1[i]<valueTable2[j] then 
				return 2
			end
		end
	end

	--能到这里说明两个同花点数相同，则比花色
	local color1 = math.modf(card1[2]/16)
	local color2 = math.modf(card2[2]/16)
	if color1 > color2 then 
		return 1
	else
		return 2
	end
end

--顺子比较
function TableLogic:CompareShunZi(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end
	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	for i=1, #valueTable1 do
		for j=i, #valueTable2 do
			if valueTable1[i]==valueTable2[j] then 
				break
			elseif valueTable1[i]>valueTable2[j] then 
				return 1
			elseif valueTable1[i]<valueTable2[j] then 
				return 2
			end
		end
	end

	--能到这里说明顺子点数相同，则比最大一张花色
	local color1 = math.modf(card1[6]/16)
	local color2 = math.modf(card2[6]/16)
	if color1 > color2 then 
		return 1
	else
		return 2
	end
end

--三条比较
function TableLogic:CompareSanTiao(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end

	local iRet1,bFindTable1 = self:CheckHasSameCards(3, valueTable1)
	local iRet2,bFindTable2 = self:CheckHasSameCards(3, valueTable2)

	if valueTable1[bFindTable1[1]]>valueTable2[bFindTable2[1]] then 
		return 1
	else
		return 2
	end
end

--取两对中的单张
function TableLogic:GetLiangDuiSinge(cardData)
	for i=2, 6 do
		local count = 0
		for j=2, 6 do
			if cardData[i]%16~=cardData[j]%16 then
				count = count + 1
			end

			if count==4 then 
				return cardData[i]
			end
		end 
	end
end

--两对比较
function TableLogic:CompareLiangDui(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	local bSelectTable1 = {}
	local bSelectTable2 = {}
	for i=2, 6 do
		--注意，一定要用table.insert. 因为CheckHasSameCards是从1开始循环遍历的
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
		table.insert(bSelectTable1, false)
		table.insert(bSelectTable2, false)
	end

	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	local iRet1,bFindTable1 = self:CheckHasSameCards(2, valueTable1, bSelectTable1)
	local iRet2,bFindTable2 = self:CheckHasSameCards(2, valueTable2, bSelectTable2)
	--用于后面比大小
	local bFind1Big = bFindTable1[1]

	if valueTable1[bFindTable1[1]] > valueTable2[bFindTable2[1]] then 
		return 1
	elseif valueTable1[bFindTable1[1]] < valueTable2[bFindTable2[1]] then 
		return 2
	else
		--对子相等，再取一次
		--skynet.error("--对子相等，再取一次")
		iRet1,bFindTable1 = self:CheckHasSameCards(2, valueTable1, bSelectTable1)
	 	iRet2,bFindTable2 = self:CheckHasSameCards(2, valueTable2, bSelectTable2)
	 	if valueTable1[bFindTable1[1]] > valueTable2[bFindTable2[1]] then 
			return 1
		elseif valueTable1[bFindTable1[1]] < valueTable2[bFindTable2[1]] then 
			return 2
		else
			--还是相等的，那就比较单张的大小
			--skynet.error("-还是相等的，那就比较单张的大小")
			local leftPos1 = self:GetUnSelectPos(bSelectTable1)
			local leftPos2 = self:GetUnSelectPos(bSelectTable2)
			if valueTable1[leftPos1] > valueTable2[leftPos2] then 
				return 1
			elseif valueTable1[leftPos1] < valueTable2[leftPos1] then 
				return 2
			else
				--skynet.error("-能到这里")
				--能到这里说明连后面的单张也一样,那就找最大的那对里谁是黑桃
				for i=2, 6 do
					if valueTable1[bFind1Big]==card1[i]%16 then 
						--skynet.error("math.modf(card1[i]/16)=", math.modf(card1[i]/16))
						if math.modf(card1[i]/16)==4 then 
							return 1
						end
					end
				end
				--到这里说明card1里没找到黑桃，那肯定就在card2里了，
				return 2
			end
		end
	end
end

--对子比较
function TableLogic:CompareDuiZi(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end

	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	local iRet1,bFindTable1 = self:CheckHasSameCards(2, valueTable1)
	local iRet2,bFindTable2 = self:CheckHasSameCards(2, valueTable2)

	if valueTable1[bFindTable1[1]] > valueTable2[bFindTable2[1]] then 
		return 1
	elseif valueTable1[bFindTable1[1]] < valueTable2[bFindTable2[1]] then 
		return 2
	else 
		--对子一样时,比单张
		for i=1, #valueTable1 do
			for j=i, #valueTable2 do
				if valueTable1[i]==valueTable2[j] then 
					break
				elseif valueTable1[i]>valueTable2[j] then 
					return 1
				elseif valueTable1[i]<valueTable2[j] then 
					return 2
				end
			end
		end

		--能到这里说明连后面的单张也一样,那就对子里谁是黑桃
		for i=2, 6 do
			if valueTable1[bFindTable1[1]]==card1[i]%16 then 
				--skynet.error("math.modf(card1[i]/16)=", math.modf(card1[i]/16))
				if math.modf(card1[i]/16)==4 then 
					return 1
				end
			end
		end
		--到这里说明card1里没找到黑桃，那肯定就在card2里了，
		return 2
	end 
end

--杂牌比较
function TableLogic:CompareZaPai(card1, card2)
	local valueTable1 = {}
	local valueTable2 = {}
	for i=2, 6 do
		table.insert(valueTable1, card1[i]%16)
		table.insert(valueTable2, card2[i]%16)
	end

	self:SortPukeBigToSmallValue(valueTable1)
	self:SortPukeBigToSmallValue(valueTable2)

	for i=1, #valueTable1 do
		for j=i, #valueTable2 do
			if valueTable1[i]==valueTable2[j] then 
				break
			elseif valueTable1[i]>valueTable2[j] then 
				return 1
			elseif valueTable1[i]<valueTable2[j] then 
				return 2
			end
		end
	end

	--能到这里说明杂牌一样，比最大牌的花色
	local color1, color2
	for i=2, 6 do
		if card1[i]%16 == valueTable1[1] then 
			color1 = math.modf(card1[i]/16)
		end
		if card2[i]%16 == valueTable2[1] then 
			color2 = math.modf(card2[i]/16)
		end
	end
	if color1 > color2 then 
		return 1
	else
		return 2
	end
end

---------------------------------------------------------------------------
function TableLogic:GiveAllCards(chair, bSelectTable)
    --余下的都是杂牌了,赋值
    --head
    if chair.chAdViseData.head[0]==nil then 
        chair.chAdViseData.head[0] = 0
        chair.chAdViseData.head[1] = EGameType.CT_SINGLE
    end
    for i=2, 4 do 
        if chair.chAdViseData.head[i]==nil then 
          	local posRet = self:GetUnSelectPos(bSelectTable)
        	if posRet ~= 0 then  
                chair.chAdViseData.head[i] = chair.chCardData[posRet]
                bSelectTable[posRet] = true
            end
         end
    end
    chair.chAdViseData.head[5] = 0
    chair.chAdViseData.head[6] = 0

    --middle
    if chair.chAdViseData.middle[0]==nil then 
        chair.chAdViseData.middle[0] = 0
        chair.chAdViseData.middle[1] = EGameType.CT_SINGLE
    end
    for i=2, 6 do 
        if chair.chAdViseData.middle[i]==nil then 
			local posRet = self:GetUnSelectPos(bSelectTable)
            if posRet ~= 0 then  
                chair.chAdViseData.middle[i] = chair.chCardData[posRet]
                bSelectTable[posRet] = true
            end
       	end    
    end

    --tail
    if chair.chAdViseData.tail[0]==nil then 
        chair.chAdViseData.tail[0] = 0
        chair.chAdViseData.tail[1] = EGameType.CT_SINGLE
    end
    for i=2, 6 do 
        if chair.chAdViseData.tail[i]==nil then 
            local posRet = self:GetUnSelectPos(bSelectTable)
            if posRet ~= 0 then  
                chair.chAdViseData.tail[i] = chair.chCardData[posRet]
                bSelectTable[posRet] = true
            end
        end   
    end
end

function TableLogic:FindTypeCards(chair, valueTable, colorTable, bSelectTable, channel)
    local iRet = false

    if channel==EGameChannel.HEAD then 
        if self:SelectSanTiao(chair, valueTable, bSelectTable, 1, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectDuiZi(chair, valueTable, bSelectTable, 1, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
    else
        if self:SelectTongHuaShun(chair, valueTable, colorTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectTieZhi(chair, valueTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectHuLu(chair, valueTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectTongHua(chair, colorTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if  self:SelectShunZi(chair, valueTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectSanTiao(chair, valueTable, bSelectTable, 1, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectLiangDui(chair, valueTable, bSelectTable, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
        if self:SelectDuiZi(chair, valueTable, bSelectTable, 1, channel)==EGameSelectStatus.COMPELETE then 
            return
        end
    end
end

--中尾道选择牌
function TableLogic:MiddOrTailInsert(chair, color, type, bFindTable, channel)
    if channel == EGameChannel.TAIL then 
        if chair.chAdViseData.tail[7] == nil then 
            chair.chAdViseData.tail[0] = color
            chair.chAdViseData.tail[1] = type
            chair.chAdViseData.tail[2] = chair.chCardData[bFindTable[1]] 
            chair.chAdViseData.tail[3] = chair.chCardData[bFindTable[2]] 
            chair.chAdViseData.tail[4] = chair.chCardData[bFindTable[3]] 
            chair.chAdViseData.tail[5] = chair.chCardData[bFindTable[4]] 
            chair.chAdViseData.tail[6] = chair.chCardData[bFindTable[5]] 
            chair.chAdViseData.tail[7] = 1
            skynet.error("MiddOrTailInsert! type=", type)
            return EGameSelectStatus.COMPELETE 
        end
    elseif channel == EGameChannel.MIDDLE then 
        if chair.chAdViseData.middle[7] == nil then 
            chair.chAdViseData.middle[0] = color
            chair.chAdViseData.middle[1] = type
            chair.chAdViseData.middle[2] = chair.chCardData[bFindTable[1]] 
            chair.chAdViseData.middle[3] = chair.chCardData[bFindTable[2]] 
            chair.chAdViseData.middle[4] = chair.chCardData[bFindTable[3]] 
            chair.chAdViseData.middle[5] = chair.chCardData[bFindTable[4]] 
            chair.chAdViseData.middle[6] = chair.chCardData[bFindTable[5]] 
            chair.chAdViseData.middle[7] = 1
            skynet.error("MiddOrTailInsert! type=", type)
            return EGameSelectStatus.COMPELETE 
        end
    end

    return EGameSelectStatus.UNCOMPELETE
end

--头道选择牌
function TableLogic:HeadFirstInsert(chair, type, bFindTable)
    --中道有牌了，就给尾道
    skynet.error("HeadFirstInsert! type=", type)
    if chair.chAdViseData.head[7] == nil then 
        chair.chAdViseData.head[0] = 0
        chair.chAdViseData.head[1] = type
        chair.chAdViseData.head[2] = chair.chCardData[bFindTable[1]] 
        chair.chAdViseData.head[3] = chair.chCardData[bFindTable[2]]  
        chair.chAdViseData.head[4] = chair.chCardData[bFindTable[3]]  
        chair.chAdViseData.head[5] = 0
        chair.chAdViseData.head[6] = 0
        chair.chAdViseData.head[7] = 1
        return EGameSelectStatus.COMPELETE  
    end
   
    return EGameSelectStatus.UNCOMPELETE
end

--从valueTable里找到所有与value值一样的坐标，再查这所有的坐标内有没有花色和color一样的，有就返回坐标位置，没有就返回0
function TableLogic:FindSameColor(color, value, valueTable, colorTable, bSelectTable)
    local posTable = {}
    for i=1, maxCardCount do
        if valueTable[i]==value and bSelectTable[i]==false then 
            table.insert(posTable, i)
        end
    end

    for i=0, #posTable do
        if color == colorTable[posTable[i]] then 
            return posTable[i]
        end
    end

    return 0
end

--BYTE head[7]; [0]:{0:非同花 1：方 2：梅 3：红 4：黑} [1]：{0：杂牌 1：对子 2：顺子 3：条子 4：同花顺} [2][3][4] 具体扑克
function TableLogic:SelectTongHuaShun(chair, valueTable, colorTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasTongHuaShun(valueTable, colorTable, bSelectTable)
	if iRet==true then 
        skynet.error("SelectTongHuaShun!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4]," ",bFindTable[5])
        return self:MiddOrTailInsert(chair, colorTable[bFindTable[1]], EGameType.CT_FIVE_STRAIGHT_FLUSH, bFindTable, channel)
    end
end

--拿出铁支
function TableLogic:SelectTieZhi(chair, valueTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasSameCards(4, valueTable, bSelectTable)
	if iRet==true then 
		skynet.error("SelectTieZhi!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4]," ",bFindTable[5])
		return self:MiddOrTailInsert(chair, 0, EGameType.CT_FIVE_FOUR_ONE, bFindTable, channel)
	end
end

--拿出葫芦
function TableLogic:SelectHuLu(chair, valueTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasHuLu(valueTable, bSelectTable)
	if iRet==true then 
		skynet.error("SelectHuLu!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4]," ",bFindTable[5])
		return self:MiddOrTailInsert(chair, 0, EGameType.CT_FIVE_THREE_DEOUBLE, bFindTable, channel)
	end

end

--拿出同花
function TableLogic:SelectTongHua(chair, colorTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasTongHua(colorTable, bSelectTable)
	if iRet==true then 
		skynet.error("SelectTongHua!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4], "", bFindTable[5])
        return self:MiddOrTailInsert(chair, colorTable[bFindTable[1]], EGameType.CT_FIVE_FLUSH, bFindTable, channel)
    end
end

--拿出顺子
function TableLogic:SelectShunZi(chair, valueTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasShunZi(5, valueTable, bSelectTable)
	if iRet==true then 
		skynet.error("SelectShunZi!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4], "", bFindTable[5])
        return self:MiddOrTailInsert(chair, 0, EGameType.CT_FIVE_MIXED_FLUSH_NO_A, bFindTable, channel)
    end

end

--拿出三条
function TableLogic:SelectSanTiao(chair, valueTable, bSelectTable, needInsert, channel)
	local iRet,bFindTable = self:CheckHasSameCards(3, valueTable, bSelectTable)
	if needInsert==0 then 
		return iRet, bFindTable
	end

	if iRet==true then 
		--需要插入牌里
        skynet.error("SelectSanTiao!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3])
        if channel ~= EGameChannel.HEAD then 
            return self:MiddOrTailInsert(chair, 0, EGameType.CT_THREE, bFindTable, channel)
        else
            return self:HeadFirstInsert(chair, EGameType.CT_THREE, bFindTable)
        end
    end
end

--拿出两对
function TableLogic:SelectLiangDui(chair, valueTable, bSelectTable, channel)
	local iRet,bFindTable = self:CheckHasLiangDui(valueTable, bSelectTable)
	if iRet==true then 
		skynet.error("SelectLiangDui!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2]," ",bFindTable[3]," ",bFindTable[4])
        return self:MiddOrTailInsert(chair, 0, EGameType.CT_FIVE_TWO_DOUBLE, bFindTable, channel)
    end
end

--拿出对子
function TableLogic:SelectDuiZi(chair, valueTable, bSelectTable, needInsert, channel)
	local iRet,bFindTable = self:CheckHasSameCards(2, valueTable, bSelectTable)
	if needInsert==0 then 
		return iRet, bFindTable
	end

	if iRet==true then 
		--需要插入牌里
        skynet.error("SelectDuiZi!, channel is=", channel, "Selected: ",bFindTable[1]," ",bFindTable[2])
        if channel ~= EGameChannel.HEAD then 
            return self:MiddOrTailInsert(chair, 0, EGameType.CT_ONE_DOUBLE, bFindTable, channel)
        else
            return self:HeadFirstInsert(chair, EGameType.CT_ONE_DOUBLE, bFindTable)
        end
    end
end
--------------------------------------------------------------------------
function TableLogic:CalculateOutCard(chOutCardData)
	chOutCardData.head[0], chOutCardData.head[1] = self:CheckHead(chOutCardData.head)

	chOutCardData.middle[0], chOutCardData.middle[1] = self:CheckMiddleOrTail(chOutCardData.middle)
	
	chOutCardData.tail[0], chOutCardData.tail[1] = self:CheckMiddleOrTail(chOutCardData.tail)
end


function TableLogic:SetSendTotalMsg(chair)
    --特殊牌型
    if chair.chOutCardData.cardgroup ~= 0 then 
        chair.chTotalSpecial = chair.chTotalSpecial + 1
    end
    --同花顺
    if chair.chOutCardData.middle[1]==EGameType.CT_FIVE_STRAIGHT_FLUSH then 
        chair.chTotalTongHuaShun = chair.chTotalTongHuaShun + 1
    end
    if chair.chOutCardData.tail[1]==EGameType.CT_FIVE_STRAIGHT_FLUSH then 
        chair.chTotalTongHuaShun = chair.chTotalTongHuaShun + 1
    end
    --铁支
    if chair.chOutCardData.middle[1]==EGameType.CT_FIVE_FOUR_ONE then 
        chair.chTotalTieZhi = chair.chTotalTieZhi + 1
    end
    if chair.chOutCardData.tail[1]==EGameType.CT_FIVE_FOUR_ONE then 
        chair.chTotalTieZhi = chair.chTotalTieZhi + 1
    end
    --冲三
    if chair.chOutCardData.head[1]==EGameType.CT_THREE then 
        chair.chTotalChongSan = chair.chTotalChongSan + 1
    end
end

--返回color和type
function TableLogic:CheckHead(head)
	local valueTable = {}
	for i=1, 3 do
		valueTable[i] = (head[i+1])%16
	end
	--排序
    self:SortValue(valueTable)

    --检测是否三条
    if self:CheckHasSameCards(3, valueTable)==true then 
    	return 0, EGameType.CT_THREE
    end
    --检测是否对子
    if self:CheckHasSameCards(2, valueTable)==true then 
    	return 0, EGameType.CT_ONE_DOUBLE
    end

	--都不是返回杂牌
	return	0, EGameType.CT_SINGLE
end

function TableLogic:CheckMiddleOrTail(middleOrTail)
	local valueTable = {}
	local colorTable = {}
	for i=1, 5 do
		valueTable[i] = (middleOrTail[i+1])%16
		colorTable[i] = math.modf(middleOrTail[i+1]/16)
	end
	--排序
    self:SortValue(valueTable)
 
    --是否同花顺
    if self:CheckHasTongHuaShun(valueTable, colorTable)==true then
    	return colorTable[1], EGameType.CT_FIVE_STRAIGHT_FLUSH
    end
    --检测铁支
    if self:CheckHasSameCards(4, valueTable)==true then 
   		return 0, EGameType.CT_FIVE_FOUR_ONE
   	end
    --检测是否是葫芦
   	if self:CheckHasHuLu(valueTable)==true then 
   		return 0, EGameType.CT_FIVE_THREE_DEOUBLE
   	end
   	--同花
    if self:CheckHasTongHua(colorTable)==true then 
    	return colorTable[1], EGameType.CT_FIVE_FLUSH
    end
    --顺子
    if self:CheckHasShunZi(5, valueTable)==true then 
    	return 0, EGameType.CT_FIVE_MIXED_FLUSH_NO_A
    end
     --检测是否三条
    if self:CheckHasSameCards(3, valueTable)==true then 
    	return 0, EGameType.CT_THREE
    end
    --检测是否为两对
    if self:CheckHasLiangDui(valueTable)==true then 
    	return 0, EGameType.CT_FIVE_TWO_DOUBLE
    end
    --检测是否对子
    if self:CheckHasSameCards(2, valueTable)==true then 
    	return 0, EGameType.CT_ONE_DOUBLE
    end
    
    --杂牌
   	return 0, EGameType.CT_SINGLE
end

function TableLogic:CheckHasTongHuaShun(valueTable, colorTable, bSelectTable)
	--A,2,3,4,5 算是特殊牌型，这里要单独拿出来检测
	if self:CheckHasAToFiveTongHua(valueTable, colorTable)==true then 
		return true
	end

	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end
	--[[
    skynet.error("---------------SelectTongHuaShun---------------")
    skynet.error("chair=", chair)
    for i=1, #valueTable do
        skynet.error("valueTable["..i.."]= ",valueTable[i])
    end
    for i=1, #colorTable do
        skynet.error("colorTable["..i.."]= ",colorTable[i])
    end
    for i=1, #bSelectTable do
        skynet.error("bSelectTable["..i.."]= ",bSelectTable[i])
    end
    skynet.error("channel=", channel)
    --]]

	 --外循环
    local checkType = 0
    local bFind1 = 0
    local bFind2 = 0
    local bFind3 = 0
    local bFind4 = 0
    local bFind5 = 0
    local tempValue = 0
    for i=1, #valueTable-1 do
        if checkType == EGameType.CT_FIVE_STRAIGHT_FLUSH then 
            break
        end

        bFind1 = 0
        bFind2 = 0
        bFind3 = 0
        bFind4 = 0
        bFind5 = 0
        tempValue = valueTable[i]
        repeat
            if bSelectTable[i] == true then
                break
            end
            
            for j=i+1, #valueTable do
                --这里还要break一次,否则跳不出
                if checkType == EGameType.CT_FIVE_STRAIGHT_FLUSH then 
                    break
                end

                if valueTable[j]==tempValue+1 and bSelectTable[j]==false then 
                    tempValue = valueTable[j]
                    if bFind2==0 then
                        bFind2 = j
                    elseif bFind3==0 then
                        bFind3 = j
                    elseif bFind4==0 then
                        bFind4 = j
                    elseif bFind5==0 then
                        bFind5 = j
                    end 

                    if bFind5~=0 then 
                        bFind1 = i
                        --找到第一张value的所有花色牌丢进v1ColorTable中
                        local v1ColorTable = {}
                        for k=1, maxCardCount do
                            if valueTable[i] == valueTable[k] then
                            table.insert(v1ColorTable, colorTable[k]) 
                            end
                        end
                        --找到同时和v1ColorTable[i]中的花色一样的四个位置。 四个同时都有时才是同花顺
                        for m=1, #v1ColorTable do
                            local iRet1 = self:FindSameColor(v1ColorTable[m], valueTable[bFind1], valueTable, colorTable, bSelectTable)
                            local iRet2 = self:FindSameColor(v1ColorTable[m], valueTable[bFind2], valueTable, colorTable, bSelectTable)
                            local iRet3 = self:FindSameColor(v1ColorTable[m], valueTable[bFind3], valueTable, colorTable, bSelectTable)
                            local iRet4 = self:FindSameColor(v1ColorTable[m], valueTable[bFind4], valueTable, colorTable, bSelectTable)
                            local iRet5 = self:FindSameColor(v1ColorTable[m], valueTable[bFind5], valueTable, colorTable, bSelectTable)
                            --skynet.error("iRet1=", iRet1)
                            --skynet.error("iRet2=", iRet2)
                            --skynet.error("iRet3=", iRet3)
                            --skynet.error("iRet4=", iRet4)
                            --skynet.error("iRet5=", iRet5)
                            if iRet2~=0 and iRet3~=0 and iRet4~=0 and iRet5~=0 then  
                                bFind1 = iRet1
                                bFind2 = iRet2
                                bFind3 = iRet3
                                bFind4 = iRet4
                                bFind5 = iRet5
                                --skynet.error("bSelectTable i=", i)
                                bSelectTable[bFind1] = true
                                bSelectTable[bFind2] = true
                                bSelectTable[bFind3] = true
                                bSelectTable[bFind4] = true
                                bSelectTable[bFind5] = true
                                --并不代表是没A得同花顺，由于是从C++搬移过来，协议码都早已订好，所有原先左右数值保留，这里用来代表同花顺
                                checkType = EGameType.CT_FIVE_STRAIGHT_FLUSH
                                break
                            end
                        end
                    end
                end
            end
        until true
    end

    if checkType==EGameType.CT_FIVE_STRAIGHT_FLUSH then 
    	local bFindTable = {}
    	table.insert(bFindTable, bFind1)
    	table.insert(bFindTable, bFind2)
    	table.insert(bFindTable, bFind3)
    	table.insert(bFindTable, bFind4)
    	table.insert(bFindTable, bFind5)
        return true, bFindTable
    end

    return false
end

function TableLogic:CheckHasTongHua(colorTable, bSelectTable)
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #colorTable do
			bSelectTable[i] = false
		end
	end

	return self:CheckHasSameColor(5, colorTable, bSelectTable) 
end

function TableLogic:CheckHasAToFive(valueTable)
	local tempValue = valueTable

	self:SortValue(tempValue)

	if tempValue[1]==2 and tempValue[2]==3 and tempValue[3]==4 and tempValue[4]==5 and tempValue[5]==14 then
		return true
	end

	return false
end

function TableLogic:CheckHasAToFiveTongHua(valueTable, colorTable)
	local tempValue = valueTable

	self:SortValue(tempValue)

	if tempValue[1]==2 and tempValue[2]==3 and tempValue[3]==4 and tempValue[4]==5 and tempValue[5]==14 then
		if colorTable[1]==colorTable[2] and colorTable[2]==colorTable[3] and colorTable[3]==colorTable[4] and colorTable[4]==colorTable[5] then 
			return true
		end
	end

	return false
end

--检测几张相同的牌， 参数一count是几张
function TableLogic:CheckHasShunZi(count, valueTable, bSelectTable)
	--A,2,3,4,5 算是特殊牌型，这里要单独拿出来检测
	if self:CheckHasAToFive(valueTable)==true then 
		return true
	end

	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end

	--其实顺子循环j可以从i+1位置开始的。因为本来就排好序了的，前面能组成顺子早组了，每组成也没必要再检测的。但是这里暂时先不改了，数据小影响可以忽略，以稳定为主
	local bFindTable = {}
	local tempValue = 0
	for i=1, #valueTable do
		bFindTable = {}
		tempValue = valueTable[i]
		repeat
			if bSelectTable[i]==true then 
				break
			end
			for j=1, #valueTable do
				repeat 
					if j==i or bSelectTable[j]==true then 
						break
					end
					if tempValue==valueTable[j]-1 then
						tempValue = valueTable[j] 
						for i=2, count do
							if bFindTable[i]==nil then 
								bFindTable[i] = j
								break
							end
						end
						--不为空说明找到了
						if bFindTable[count] ~= nil then 
							bFindTable[1] = i
							for i=1, #bFindTable do
								bSelectTable[bFindTable[i]] = true
							end
							return true, bFindTable 
						end
					end
				until true	
			end
		until true
	end

	return false
end

--检测几张相同的牌， 参数一count是几张
function TableLogic:CheckHasSameCards(count, valueTable, bSelectTable)
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end

	local bFindTable = {}
	for i=1, #valueTable do
		bFindTable = {}
		repeat
			if bSelectTable[i]==true then 
				break
			end
			for j=1, #valueTable do
				repeat 
					if j==i or bSelectTable[j]==true then 
						break
					end
					if valueTable[i]==valueTable[j] then 
						for i=2, count do
							if bFindTable[i]==nil then 
								bFindTable[i] = j
								break
							end
						end
						--不为空说明找到了
						if bFindTable[count] ~= nil then 
							bFindTable[1] = i
							for i=1, #bFindTable do
								bSelectTable[bFindTable[i]] = true
							end
							return true, bFindTable 
						end
					end
				until true	
			end
		until true
	end

	return false
end

--检测几张花色相同的牌， 参数一count是几张
function TableLogic:CheckHasSameColor(count, colorTable, bSelectTable)
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #colorTable do
			bSelectTable[i] = false
		end
	end

	local bFindTable = {}
	for i=1, #colorTable do
		bFindTable = {}
		repeat
			if bSelectTable[i]==true then 
				break
			end
			for j=1, #colorTable do
				repeat 
					if j==i or bSelectTable[j]==true then 
						break
					end
					if colorTable[i]==colorTable[j] then 
						for i=2, count do
							if bFindTable[i]==nil then 
								bFindTable[i] = j
								break
							end
						end
						--不为空说明找到了
						if bFindTable[count] ~= nil then 
							bFindTable[1] = i
							for i=1, #bFindTable do
								bSelectTable[bFindTable[i]] = true
							end
							return true, bFindTable 
						end
					end
				until true	
			end
		until true
	end

	return false
end

function TableLogic:CheckHasLiangDui(valueTable, bSelectTable)
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end

	local  bFindTable = {}
	--选两次对子即可
	local iRet,iTable = self:CheckHasSameCards(2, valueTable, bSelectTable)
	if iRet==true then
		for i=1, #iTable do
			table.insert(bFindTable, iTable[i])
		end
		iRet,iTable = self:CheckHasSameCards(2, valueTable, bSelectTable)
		if iRet==true then 
			for i=1, #iTable do
			table.insert(bFindTable, iTable[i])
			end
			return true, bFindTable
		end
	end

	for i=1, #bFindTable do
		bSelectTable[bFindTable[i]] = false
	end
	return false
end

function TableLogic:CheckHasHuLu(valueTable, bSelectTable)
	--兼容不需要从已经选过的牌堆内选牌时的算法
	if bSelectTable==nil then 
		bSelectTable = {}
		for i=1, #valueTable do
			bSelectTable[i] = false
		end
	end

	--找一次三条找一次对子
	local  bFindTable = {}
	local iRet,iTable = self:CheckHasSameCards(3, valueTable, bSelectTable) 
	if iRet==true then
		for i=1, #iTable do
			table.insert(bFindTable, iTable[i])
		end
		iRet,iTable = self:CheckHasSameCards(2, valueTable, bSelectTable)
		if iRet==true then 
			for i=1, #iTable do
			table.insert(bFindTable, iTable[i])
			end
			return true, bFindTable
		end
	end

	for i=1, #bFindTable do
		bSelectTable[bFindTable[i]] = false
	end
	return false
end

function TableLogic:SortPuke(chCardData)
    if chCardData and #chCardData > 1 then
        table.sort(chCardData, function(a, b)
            return a%16 < b%16
        end)
    end

    for i=1, #chCardData do 
        --skynet.error("after sort chCardData=", chCardData[i])
    end
end

function TableLogic:SortPukeBigToSmall(chCardData)
    if chCardData and #chCardData > 1 then
        table.sort(chCardData, function(a, b)
            return a%16 > b%16
        end)
    end

    for i=1, #chCardData do 
        --skynet.error("after sort chCardData=", chCardData[i])
    end
end

function TableLogic:SortPukeBigToSmallValue(valueTable)
    if valueTable and #valueTable > 1 then
        table.sort(valueTable, function(a, b)		
            return a > b
        end)
    end

    for i=1, #valueTable do 
        --skynet.error("after sort valueTable=", valueTable[i])
    end
end


function TableLogic:SortValue(valueTable)
    if valueTable and #valueTable > 1 then
        table.sort(valueTable, function(a, b)
            return a < b
        end)
    end

    for i=1, #valueTable do 
        --skynet.error("after sort chCardData=", chCardData[i])
    end
end

function TableLogic:SortSameValueColor(puke)
	local colorTable = {}
 	for i=1, #puke-1 do
 		colorTable = {}
 		table.insert(colorTable, puke[i])
 		for j=i+1, #puke do
 			if puke[i]%16~=puke[j]%16 or j==#puke then 
 				if j==#puke and puke[i]%16==puke[j]%16 then 
 					table.insert(colorTable, puke[j])
 				end
 				if #colorTable > 1 then 
 					table.sort(colorTable, function(a, b)
 						return math.modf(a/16) > math.modf(b/16)
 					end)

 					for k=1, #colorTable do
 						puke[i+k-1] = colorTable[k]
 					end 
 				end
 				break
 			end
 			table.insert(colorTable, puke[j])
 		end
 	end
end 


return TableLogic